package com.cooldatasoft.taskManager.component;

import java.util.Collection;
import java.util.Iterator;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Configurable;

import com.cooldatasoft.domain.model.Document;
import com.cooldatasoft.domain.model.DocumentEntry;
import com.cooldatasoft.domain.model.DocumentType;
import com.cooldatasoft.domain.model.Project;
import com.cooldatasoft.domain.model.RolesEnum;
import com.cooldatasoft.domain.service.DocumentEntryService;
import com.cooldatasoft.domain.service.DocumentService;
import com.cooldatasoft.security.TaskManagerSecurityManager;
import com.cooldatasoft.taskManager.TaskManagerApplication;
import com.vaadin.Application;
import com.vaadin.annotations.AutoGenerated;
import com.vaadin.data.Container.Sortable;
import com.vaadin.data.Item;
import com.vaadin.data.util.HierarchicalContainer;
import com.vaadin.data.util.ItemSorter;
import com.vaadin.data.validator.StringLengthValidator;
import com.vaadin.event.Action;
import com.vaadin.event.DataBoundTransferable;
import com.vaadin.event.ItemClickEvent;
import com.vaadin.event.Transferable;
import com.vaadin.event.dd.DragAndDropEvent;
import com.vaadin.event.dd.DropHandler;
import com.vaadin.event.dd.acceptcriteria.AcceptAll;
import com.vaadin.event.dd.acceptcriteria.AcceptCriterion;
import com.vaadin.terminal.ExternalResource;
import com.vaadin.terminal.Resource;
import com.vaadin.terminal.ThemeResource;
import com.vaadin.terminal.gwt.client.ui.dd.VerticalDropLocation;
import com.vaadin.ui.AbsoluteLayout;
import com.vaadin.ui.Alignment;
import com.vaadin.ui.Button;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.CustomComponent;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.Link;
import com.vaadin.ui.NativeButton;
import com.vaadin.ui.ProgressIndicator;
import com.vaadin.ui.RichTextArea;
import com.vaadin.ui.TextField;
import com.vaadin.ui.Tree;
import com.vaadin.ui.Tree.TreeDragMode;
import com.vaadin.ui.Tree.TreeTargetDetails;
import com.vaadin.ui.VerticalLayout;

@SuppressWarnings("serial")
@Configurable(preConstruction = true)
public class GuideView extends CustomComponent {

	@AutoGenerated
	private AbsoluteLayout mainLayout;
	@AutoGenerated
	private HorizontalLayout horizontalLayout;
	@AutoGenerated
	private VerticalLayout verticalLayout;
	@AutoGenerated
	private HorizontalLayout horizontalLayout_1;
	@AutoGenerated
	private NativeButton myUpdateButton;
	@AutoGenerated
	private RichTextArea myTextArea;
	@AutoGenerated
	private TextField myHeaderTextBox;
	@AutoGenerated
	private AbsoluteLayout absoluteLayout_2;
	@AutoGenerated
	private Tree mySectionsTree;

	@Autowired
	private DocumentService myDocumentService;
	
	@Autowired
	private DocumentEntryService myDocumentEntryService;
	
	@Autowired
	private TaskManagerSecurityManager mySecurityManager;
	
//	@Autowired
//	private UserService myUserService;
//	
//	@Autowired
//	private TaskService myTaskService;
	
	private Project myCurrentProject;
	private DocumentType myType;
	private Document myDocument;
	private DocumentEntry myCurrentEntry;
	private HierarchicalContainer myContainer;
	
	private ProgressIndicator progressIndicator;
	private NativeButton generateDocumentation;
	private Worker1 worker1;
	private Link generatePdfBtn;
	private ThemeResource PDF_ICON = new ThemeResource("../centrumprosperitytheme/images/pdf.png");

	private static final Action ADD = new Action("Insert section");
	private static final Action DELETE = new Action("Delete section and all subsections");
	private static final String DOUBLE_FIELD_WIDTH = "30em";
	
	public GuideView(Project project, DocumentType type_in) {
		this.myCurrentProject = project;
		this.myType = type_in;
		this.myDocument = myDocumentService.getByProjectAndType(myCurrentProject, myType);
		ensureDocument();
		
		buildMainLayout();
		setCompositionRoot(mainLayout);
		
		customizeComponents();
		
		resetSectionData();
		
		customizeGenerateBtn();
		
		addDownloadLink();
	}
	
	private void addDownloadLink() {
		// generatePdfBtn
		Application app = TaskManagerApplication.getInstance();
		Resource resource = new ExternalResource(app.getURL()
				+ "documentation/?pid="
				+ String.valueOf(myCurrentProject.getIdProject())
				+ "&ptid="
				+ (getDocTypeEnumValue(myDocument)));

		generatePdfBtn = new Link("Download documentation", resource);
		generatePdfBtn.setImmediate(false);
		generatePdfBtn.setIcon(PDF_ICON);
		generatePdfBtn.setVisible(false);
		generatePdfBtn.setWidth("-1px");
		generatePdfBtn.setHeight("-1px");
		generatePdfBtn.setStyleName("pdfButton");
		horizontalLayout_1.addComponent(generatePdfBtn);
		horizontalLayout_1.setComponentAlignment(generatePdfBtn, new Alignment(33));
	}
	
	private int getDocTypeEnumValue(Document doc) {
		if(doc.getType().equals(DocumentType.USER_GUIDE)) {
			return 1;
		} else {
			return 2;
		}
	}
	
	private void customizeComponents() {
		myContainer = new HierarchicalContainer();
		myContainer.addContainerProperty("section", DocumentEntry.class, null);
	    myContainer.setItemSorter(new NoSorter());
		mySectionsTree.setContainerDataSource(myContainer);
		mySectionsTree.setDragMode(TreeDragMode.NODE);
		mySectionsTree.setDropHandler(new TreeSortDropHandler(mySectionsTree, myContainer, myDocumentEntryService, this));

		loadTree();
		addClickHandler();
		createContextMenu();
		
		myHeaderTextBox.setMaxLength(25);
		myHeaderTextBox.setRequiredError("Please enter a project name");
		myHeaderTextBox.setWidth(DOUBLE_FIELD_WIDTH);
		myHeaderTextBox.addValidator(new StringLengthValidator("Name must be 3-25 characters", 3, 50, false));
		
		myUpdateButton.addListener(new Button.ClickListener() {
			
			@Override
			public void buttonClick(ClickEvent event) {
				myCurrentEntry.setHeader(myHeaderTextBox.getValue().toString());
				myCurrentEntry.setText(myTextArea.getValue().toString());
//				System.out.println(myTextArea.getValue().toString());
//				ItextGenerator gen = new ItextGenerator(myCurrentProject);
				myDocumentEntryService.updateDocumentEntry(myCurrentEntry);
				loadTree();
			}
		});
	}
	
	private void customizeGenerateBtn() {
		progressIndicator = new ProgressIndicator();
		progressIndicator.setIndeterminate(false);
		progressIndicator.setVisible(false);		
		progressIndicator.setWidth(DOUBLE_FIELD_WIDTH);
		
		generateDocumentation = new NativeButton("Generate Documentation", new Button.ClickListener() {			
			@Override
			public void buttonClick(ClickEvent event) {
				worker1 = new Worker1();
                worker1.start();
                progressIndicator.setVisible(true);
                progressIndicator.setValue(0f);
                generateDocumentation.setEnabled(false);
			}
		});
		generateDocumentation.setStyleName("defaultBtn");
		horizontalLayout_1.addComponent(generateDocumentation);
		horizontalLayout_1.setComponentAlignment(generateDocumentation, Alignment.MIDDLE_CENTER);
		horizontalLayout_1.addComponent(progressIndicator);
		horizontalLayout_1.setComponentAlignment(progressIndicator, Alignment.MIDDLE_CENTER);
	}
	
	public void prosessed() {
        int i = worker1.getCurrent();
        if (i == Worker1.MAX) {
            progressIndicator.setVisible(false);
            generateDocumentation.setEnabled(true);
            progressIndicator.setValue(1f);
        } else {
            progressIndicator.setValue((float) i / Worker1.MAX);
        }
    }

public class Worker1 extends Thread {
    int current = 1;
    public final static int MAX = 5;

    @Override
    public void run() {
        for (; current <= MAX; current++) {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            synchronized (getApplication()) {
                prosessed();
            }
        }
        generatePdfBtn.setVisible(true);
    }

    public int getCurrent() {
        return current;
    }

}
	
	private void addClickHandler() {
		mySectionsTree.addListener(new ItemClickEvent.ItemClickListener() {

			private static final long serialVersionUID = 1L;

			@Override
			public void itemClick(ItemClickEvent event) {

				Item item = mySectionsTree.getItem(event.getItemId());
				if (item != null) {
					DocumentEntry section = (DocumentEntry) item.getItemProperty("section").getValue();
					if (section != null && section.getParentEntry() != null) {
						loadSectionData(section);
					} else {
						resetSectionData();
					}
				}
			}
		});
	}
	
	private void loadSectionData(DocumentEntry section_in) {
		myCurrentEntry = section_in;
		
		myHeaderTextBox.setValue(section_in.getHeader());
		myTextArea.setValue(section_in.getText());
		
		myUpdateButton.setEnabled(true);
		myHeaderTextBox.setEnabled(true);
		myTextArea.setEnabled(true);
	}
	
	private void resetSectionData() {
		myCurrentEntry = null;
		
		myHeaderTextBox.setValue("");
		myTextArea.setValue("");
		
		myUpdateButton.setEnabled(false);
		myHeaderTextBox.setEnabled(false);
		myTextArea.setEnabled(false);
	}
	
	private void createContextMenu() {
		mySectionsTree.addActionHandler(new Action.Handler() {

			private static final long serialVersionUID = 1L;

			public void handleAction(Action action, Object sender,
					final Object target) {
				if (action == ADD) {
					handleAddAction(target);	
				} 
				else if (action == DELETE) {
					handleDeleteAction(target);
				} 
			}

			public Action[] getActions(Object target, Object sender) {
				if (mySecurityManager.getCurrentUser().getSystemRole() == RolesEnum.LECTOR) {
					return null;
				}
				
				if (myContainer.getParent(target) == null) {
					return new Action[] { ADD };
				}
				
				return new Action[] { ADD, DELETE };
			}
		});
	}
	
	private void handleAddAction(Object target_in) {		
        
		DocumentEntry entry = (DocumentEntry) mySectionsTree
				.getItem(target_in).getItemProperty("section")
				.getValue();
		
		int order = myDocumentEntryService.getById(entry.getId()) .getDocumentEntries().size() + 1;
		
		DocumentEntry newSection = new DocumentEntry();
		newSection.setDocument(myDocument);
		newSection.setHeader("New Section");
		newSection.setParentEntry(entry);
		newSection.setOrderInGroup(order);
		newSection.setText("Section content");
		newSection.setId(myDocumentEntryService.insertDocumentEntry(newSection));
		
		addEntry(newSection, target_in);
	}
	
	private void handleDeleteAction(Object target_in) {
		DocumentEntry entry = (DocumentEntry) mySectionsTree
				.getItem(target_in).getItemProperty("section")
				.getValue();
		
		DocumentEntry realEntry = myDocumentEntryService.getById(entry.getId());
				
		// correct order in group
		int realEntryOrder = realEntry.getOrderInGroup();
		long parentId = realEntry.getParentEntry().getId();
		
		deleteRecursively(realEntry);
		removeItemFromTree(target_in);
		
		// correct order in group
		DocumentEntry parent = myDocumentEntryService.getById(parentId);
		for (DocumentEntry childEntry : parent.getDocumentEntries()) {
			if (childEntry.getOrderInGroup() > realEntryOrder) {
				childEntry.setOrderInGroup(childEntry.getOrderInGroup() - 1);
				myDocumentEntryService.updateDocumentEntry(childEntry);
			}
		}
		
	}
	
	private void deleteRecursively(DocumentEntry entry) {
		for (DocumentEntry child : entry.getDocumentEntries()) {
			deleteRecursively(child);
		}
		
		myDocumentEntryService.deleteDocumentEntry(entry);
	}
	
	private void loadTree() {

		mySectionsTree.removeAllItems();
		
		for (DocumentEntry section : myDocumentEntryService.getByDocument(myDocument)) {
			// top section has no parent
			if (section.getParentEntry() == null) {			
				// sub sections are loaded recursively
				loadSubSection(section, null);
				break;
			}
		}
		
		// expand all nodes
        for (Iterator<?> it = mySectionsTree.rootItemIds().iterator(); it.hasNext();) {
        	mySectionsTree.expandItemsRecursively(it.next());
        }
        
        myContainer.sort(new Object[]{"section"}, new boolean[]{true});
	}
	
	private void loadSubSection(DocumentEntry entry_in, Object parent_in) {
		
		Object sectionItemId = addEntry(entry_in, parent_in);
		
		for (DocumentEntry subSection : entry_in.getDocumentEntries()) {
			loadSubSection(subSection, sectionItemId);
		}
	}
	
	private Object addEntry(DocumentEntry entry_in, Object parent_in) {
		mySectionsTree.setChildrenAllowed(parent_in, true);
		mySectionsTree.expandItem(parent_in);
		
		Object sectionItemId = mySectionsTree.addItem();
		mySectionsTree.setParent(sectionItemId, parent_in);	
		mySectionsTree.setChildrenAllowed(sectionItemId, true);
		
		myContainer.getItem(sectionItemId).getItemProperty("section").setValue(entry_in);
        
		mySectionsTree.setItemCaption(sectionItemId, mySectionsTree
				      .getItem(sectionItemId).getItemProperty("section").getValue()
				      .toString());
		
		return sectionItemId;
	}
	
	public void removeItemFromTree(Object target_in) {
		 Object parent = mySectionsTree.getParent(target_in);
         myContainer.removeItemRecursively(target_in);
         
         // If the deleted object's parent has no more children, set it's
         // childrenallowed property to false (= leaf node)
         if (parent != null) {
             Collection<?> children = mySectionsTree.getChildren(parent);
             if (children != null && children.isEmpty()) {
            	 mySectionsTree.setChildrenAllowed(parent, false);
             }
         }
	}
	
	private void ensureDocument() {
		if (myDocument == null) {
			myDocument = new Document();
			myDocument.setProject(myCurrentProject);
			myDocument.setType(myType);
			
			// title will be in template. is it needed ???
			myDocument.setId(myDocumentService.insertDocument(myDocument));
			
			DocumentEntry rootEntry = new DocumentEntry();
			rootEntry.setDocument(myDocument);
			rootEntry.setHeader("Sections");
			rootEntry.setParentEntry(null);
			rootEntry.setText("");
			rootEntry.setId(myDocumentEntryService.insertDocumentEntry(rootEntry));
		}
	}
	
	 private static class TreeSortDropHandler implements DropHandler {
	        private final Tree myTree;

	        @Autowired
	        private DocumentEntryService myDocumentEntryService;
	        
	        private GuideView myGuideView;
	        
	        public TreeSortDropHandler(Tree tree, HierarchicalContainer container, DocumentEntryService service, GuideView view_in) {
	            this.myTree = tree;
	            this.myDocumentEntryService = service;
	            this.myGuideView = view_in;
	        }

	        public AcceptCriterion getAcceptCriterion() {
	            // Alternatively, could use the following criteria to eliminate some
	            // checks in drop():
	            // new And(IsDataBound.get(), new DragSourceIs(tree));
	            return AcceptAll.get();
	        }

	        public void drop(DragAndDropEvent dropEvent) {
	            // Called whenever a drop occurs on the component

	            // Make sure the drag source is the same tree
	            Transferable tree = dropEvent.getTransferable();

	            // see the comment in getAcceptCriterion()
	            if (tree.getSourceComponent() != myTree || !(tree instanceof DataBoundTransferable)) {
	                return;
	            }

	            TreeTargetDetails dropData = ((TreeTargetDetails) dropEvent.getTargetDetails());

	            Object sourceItemId = ((DataBoundTransferable) tree).getItemId();
	            Object targetItemId = dropData.getItemIdOver();

	            // Location describes on which part of the node the drop took
	            // place
	            VerticalDropLocation location = dropData.getDropLocation();

	            moveNode(sourceItemId, targetItemId, location);
	            
	            myGuideView.loadTree();
	        }

	        /**
	         * Move a node within a tree onto, above or below another node depending
	         * on the drop location.
	         * 
	         * @param sourceItemId
	         *            id of the item to move
	         * @param targetItemId
	         *            id of the item onto which the source node should be moved
	         * @param location
	         *            VerticalDropLocation indicating where the source node was
	         *            dropped relative to the target node
	         */
	        private void moveNode(Object sourceItemId, Object targetItemId, VerticalDropLocation location) {
	            HierarchicalContainer container = (HierarchicalContainer) myTree.getContainerDataSource();

	            // Sorting goes as
	            // - If dropped ON a node, we append it as a child
	            // - If dropped on the TOP part of a node, we move/add it before
	            // the node
	            // - If dropped on the BOTTOM part of a node, we move/add it
	            // after the node

	            if (location == VerticalDropLocation.MIDDLE) {
	            	
	                if (container.setParent(sourceItemId, targetItemId)
	                        && container.hasChildren(targetItemId)) {
	                    // move first in the container
		            	DocumentEntry source = getSectionItem(sourceItemId);     	
		            	DocumentEntry targetParent = getSectionItem(targetItemId);
		            	
     	            	for (DocumentEntry child : source.getParentEntry().getDocumentEntries()) {
	            			if (child.getOrderInGroup() > source.getOrderInGroup()
			            		&& child != source) {
			            			
		            			child.setOrderInGroup(child.getOrderInGroup() - 1);
		            			myDocumentEntryService.updateDocumentEntry(child);
	            			}
	            		}
		            	
		            	source.setParentEntry(targetParent);
		            	
		            	source.setOrderInGroup(targetParent.getDocumentEntries().size() + 1);
		            	myDocumentEntryService.updateDocumentEntry(source);
	                }
	            } else if (location == VerticalDropLocation.TOP) {
	                Object parentId = container.getParent(targetItemId);
	                if (parentId != null) {
	                	
	                	  if (container.setParent(sourceItemId, parentId)) {
	  		                
	  		            	DocumentEntry source = getSectionItem(sourceItemId);           	
	  		            	DocumentEntry parent = getSectionItem(parentId);
	  		            	DocumentEntry target = getSectionItem(targetItemId);
	  		            	
	  		            	if (source.getParentEntry().getId() != parent.getId()) {
	  		            		
	  		            		for (DocumentEntry child : source.getParentEntry().getDocumentEntries()) {
	  		            			if (child.getOrderInGroup() > source.getOrderInGroup()
	  				            		&& child != source) {
	  				            			
	  			            			child.setOrderInGroup(child.getOrderInGroup() - 1);
	  			            			myDocumentEntryService.updateDocumentEntry(child);
	  		            			}
	  		            		}
	  		            		
	  		            		source.setParentEntry(parent);
	  		            		source.setOrderInGroup(target.getOrderInGroup());
	  			            	myDocumentEntryService.updateDocumentEntry(source);
	  			            	
	  			            	for (DocumentEntry child : parent.getDocumentEntries()) {
	  			            		if (child.getOrderInGroup() >= source.getOrderInGroup()) {	
	  			            			child.setOrderInGroup(child.getOrderInGroup() + 1);
	  			            			myDocumentEntryService.updateDocumentEntry(child);
	  			            		}
	  			            	}
	  			            	
	  		            	} else {
	  		            	  			            	
	  			            	for (DocumentEntry child : parent.getDocumentEntries()) {
	  			            		if (child.getOrderInGroup() >= target.getOrderInGroup()
	  			            			&& child.getOrderInGroup() < source.getOrderInGroup()
	  			            			&& child != source) {
	  			            			
	  			            			child.setOrderInGroup(child.getOrderInGroup() + 1);
	  			            			myDocumentEntryService.updateDocumentEntry(child);
	  			            		}
	  			            	}
	  			            	
	  			            	source.setOrderInGroup(target.getOrderInGroup() - 1);
	  			            	myDocumentEntryService.updateDocumentEntry(source);
	  		            	}
	  	                }
	                }
	            } else if (location == VerticalDropLocation.BOTTOM) {
	                Object parentId = container.getParent(targetItemId);
	            	
	                if (container.setParent(sourceItemId, parentId)) {
		                
		            	DocumentEntry source = getSectionItem(sourceItemId);           	
		            	DocumentEntry parent = getSectionItem(parentId);
		            	DocumentEntry target = getSectionItem(targetItemId);
		            	
		            	if (source.getParentEntry().getId() != parent.getId()) {
		            		
		            		for (DocumentEntry child : source.getParentEntry().getDocumentEntries()) {
		            			if (child.getOrderInGroup() > source.getOrderInGroup()
		            				&& child.getOrderInGroup() < target.getOrderInGroup()
				            		&& child != source) {
				            			
			            			child.setOrderInGroup(child.getOrderInGroup() - 1);
			            			myDocumentEntryService.updateDocumentEntry(child);
		            			}
		            		}
		            		
		            		source.setParentEntry(parent);
		            		source.setOrderInGroup(target.getOrderInGroup() + 1);
			            	myDocumentEntryService.updateDocumentEntry(source);
			            	
			            	for (DocumentEntry child : parent.getDocumentEntries()) {
			            		if (child.getOrderInGroup() >= source.getOrderInGroup()) {	
			            			child.setOrderInGroup(child.getOrderInGroup() + 1);
			            			myDocumentEntryService.updateDocumentEntry(child);
			            		}
			            	}
			            	
		            	} else {
			            	
			            	for (DocumentEntry child : parent.getDocumentEntries()) {
			            		if (child.getOrderInGroup() <= target.getOrderInGroup()
			            			&& child.getOrderInGroup() > source.getOrderInGroup()
			            			&& child != source) {
			            			
			            			child.setOrderInGroup(child.getOrderInGroup() - 1);
			            			myDocumentEntryService.updateDocumentEntry(child);
			            		}
			            	}
			            	
			            	source.setOrderInGroup(target.getOrderInGroup() + 1);
			            	myDocumentEntryService.updateDocumentEntry(source);
		            	}
	                }
	            }
	        }
	        
	        private DocumentEntry getSectionItem(Object itemId_in) {
	        	return  (DocumentEntry) myTree.getItem(itemId_in).getItemProperty("section").getValue();
	        }
	    }
	 
	 private class NoSorter implements ItemSorter {

		private Sortable myContainer;

		@Override
		public void setSortProperties(Sortable container, Object[] propertyId,
				boolean[] ascending) {
			
			myContainer = container;
			
		}

		@Override
		public int compare(Object itemId1, Object itemId2) {
			DocumentEntry firstEntry = getSectionItem(itemId1);
			DocumentEntry secondEntry = getSectionItem(itemId2);
			if (firstEntry.getOrderInGroup() > secondEntry.getOrderInGroup()) {
				return 1;
			} else {
			    return -1;
			}
		}
		
		private DocumentEntry getSectionItem(Object itemId_in) {
	        return  (DocumentEntry) myContainer.getItem(itemId_in).getItemProperty("section").getValue();
	    }
		 
	 }

	@AutoGenerated
	private AbsoluteLayout buildMainLayout() {
		// common part: create layout
		mainLayout = new AbsoluteLayout();
		mainLayout.setImmediate(false);
		mainLayout.setWidth("100%");
		mainLayout.setHeight("100%");
		mainLayout.setMargin(false);
		
		// top-level component properties
		setWidth("100.0%");
		setHeight("100.0%");
		
		// horizontalLayout
		horizontalLayout = buildHorizontalLayout();
		mainLayout.addComponent(horizontalLayout, "top:0.0px;left:0.0px;");
		
		return mainLayout;
	}

	@AutoGenerated
	private HorizontalLayout buildHorizontalLayout() {
		// common part: create layout
		horizontalLayout = new HorizontalLayout();
		horizontalLayout.setImmediate(false);
		horizontalLayout.setWidth("100.0%");
		horizontalLayout.setHeight("100.0%");
		horizontalLayout.setMargin(true);
		horizontalLayout.setSpacing(true);
		
		// absoluteLayout_2
		absoluteLayout_2 = buildAbsoluteLayout_2();
		horizontalLayout.addComponent(absoluteLayout_2);
		horizontalLayout.setExpandRatio(absoluteLayout_2, 1.0f);
		
		// verticalLayout
		verticalLayout = buildVerticalLayout();
		horizontalLayout.addComponent(verticalLayout);
		horizontalLayout.setExpandRatio(verticalLayout, 2.0f);
		
		return horizontalLayout;
	}

	@AutoGenerated
	private AbsoluteLayout buildAbsoluteLayout_2() {
		// common part: create layout
		absoluteLayout_2 = new AbsoluteLayout();
		absoluteLayout_2.setImmediate(false);
		absoluteLayout_2.setWidth("100.0%");
		absoluteLayout_2.setHeight("100.0%");
		absoluteLayout_2.setMargin(false);
		
		// mySectionsTree
		mySectionsTree = new Tree();
		mySectionsTree.setImmediate(true);
		mySectionsTree.setWidth("-1px");
		mySectionsTree.setHeight("-1px");
		absoluteLayout_2.addComponent(mySectionsTree, "top:0.0px;left:0.0px;");
		
		return absoluteLayout_2;
	}

	@AutoGenerated
	private VerticalLayout buildVerticalLayout() {
		// common part: create layout
		verticalLayout = new VerticalLayout();
		verticalLayout.setImmediate(false);
		verticalLayout.setWidth("100.0%");
		verticalLayout.setHeight("100.0%");
		verticalLayout.setMargin(false);
		verticalLayout.setSpacing(true);
		
		// myHeaderTextBox
		myHeaderTextBox = new TextField();
		myHeaderTextBox.setCaption("Header");
		myHeaderTextBox.setImmediate(true);
		myHeaderTextBox.setWidth("150px");
		myHeaderTextBox.setHeight("-1px");
		myHeaderTextBox.setRequired(true);
		verticalLayout.addComponent(myHeaderTextBox);
		
		// myTextArea
		myTextArea = new RichTextArea();
		myTextArea.setImmediate(false);
		myTextArea.setWidth("100.0%");
		myTextArea.setHeight("100.0%");
		verticalLayout.addComponent(myTextArea);
		verticalLayout.setExpandRatio(myTextArea, 1.0f);
		
		// horizontalLayout_1
		horizontalLayout_1 = buildHorizontalLayout_1();
		verticalLayout.addComponent(horizontalLayout_1);
		
		return verticalLayout;
	}

	@AutoGenerated
	private HorizontalLayout buildHorizontalLayout_1() {
		// common part: create layout
		horizontalLayout_1 = new HorizontalLayout();
		horizontalLayout_1.setImmediate(false);
		horizontalLayout_1.setWidth("100.0%");
		horizontalLayout_1.setHeight("-1px");
		horizontalLayout_1.setMargin(false);
		
		// myUpdateButton
		myUpdateButton = new NativeButton();
		myUpdateButton.setCaption("Update");
		myUpdateButton.setImmediate(true);
		myUpdateButton.setWidth("-1px");
		myUpdateButton.setHeight("-1px");
		myUpdateButton.setStyleName("defaultBtn");
		horizontalLayout_1.addComponent(myUpdateButton);
		
		return horizontalLayout_1;
	}
}
